home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gnat1792.zip
/
gnat179b
/
t-adainc
/
s-taspri.adb
< prev
next >
Wrap
Text File
|
1994-05-19
|
23KB
|
745 lines
------------------------------------------------------------------------------
-- --
-- GNU ADA RUNTIME LIBRARY (GNARL) COMPONENTS --
-- --
-- S Y S T E M . T A S K _ P R I M I T I V E S --
-- --
-- B o d y --
-- --
-- $Revision: 1.6 $ --
-- --
-- Copyright (c) 1991,1992,1993, FSU, All Rights Reserved --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU Library General Public License as published by the --
-- Free Software Foundation; either version 2, or (at your option) any --
-- later version. GNARL is distributed in the hope that it will be use- --
-- ful, but but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Gen- --
-- eral Library Public License for more details. You should have received --
-- a copy of the GNU Library General Public License along with GNARL; see --
-- file COPYING. If not, write to the Free Software Foundation, 675 Mass --
-- Ave, Cambridge, MA 02139, USA. --
-- --
------------------------------------------------------------------------------
with Unchecked_Deallocation;
with System.POSIX_Error; use System.POSIX_Error;
with System.POSIX_timers;
with Unchecked_Conversion;
package body System.Task_Primitives is
Abort_Signal : constant Signal := SIGUSR1;
function "=" (L, R : System.Address) return Boolean
renames System."=";
ATCB_Key : pthread_key_t;
Abort_Handler : Abort_Handler_Pointer;
LL_Signals : Signal_Set;
Task_Signal_Mask : Signal_Set;
Reserved_Signals : Signal_Set;
Assertions_Checked : constant Boolean := True;
procedure Put_Character (C : Integer);
pragma Import (C, Put_Character, "putchar");
procedure Prog_Exit (Status : Integer);
pragma Import (C, Prog_Exit, "exit");
function Pointer_to_Address is new
Unchecked_Conversion (TCB_Ptr, System.Address);
function Address_to_Pointer is new
Unchecked_Conversion (System.Address, TCB_Ptr);
-----------------------
-- Local Subprograms --
-----------------------
function Get_Stack_Limit return System.Address;
pragma Inline (Get_Stack_Limit);
-- Obtains stack limit from TCB
procedure Assert (B : Boolean; M : String);
pragma Inline (Assert);
-- Output string M if B is True and Assertions_Checked
procedure Write_Character (C : Character);
procedure Write_EOL;
procedure Write_String (S : String);
-- Debugging procedures used for assertion output
---------------------
-- Write_Character --
---------------------
procedure Write_Character (C : Character) is
begin
Put_Character (Character'Pos (C));
end Write_Character;
---------------
-- Write_Eol --
---------------
procedure Write_EOL is
begin
Write_Character (Ascii.LF);
end Write_EOL;
------------------
-- Write_String --
------------------
procedure Write_String (S : String) is
begin
for J in S'range loop
Write_Character (S (J));
end loop;
end Write_String;
---------------
-- LL_Assert --
---------------
procedure LL_Assert (B : Boolean; M : String) is
begin
if not B then
Write_String ("Failed assertion: ");
Write_String (M);
Write_String (".");
Write_EOL;
Prog_Exit (1);
end if;
end LL_Assert;
------------
-- Assert --
------------
procedure Assert (B : Boolean; M : String) is
begin
if Assertions_Checked then
LL_Assert (B, M);
end if;
end Assert;
-------------------------
-- Initialize_LL_Tasks --
-------------------------
procedure Initialize_LL_Tasks (T : TCB_Ptr) is
Old_Set : Signal_Set;
Mask : Signal_Set;
Result : Return_Code;
begin
-- WARNING : SIGALRM should not be in the following mask. SIGALRM should
-- be a normal user signal under 1, and should be enabled
-- by the client. However, the current RTS built on 1
-- uses nanosleep () and pthread_cond_wait (), which fail if all
-- threads have SIGALRM masked. ???
Delete_All_Signals (LL_Signals);
Add_Signal (LL_Signals, Abort_Signal);
Add_Signal (LL_Signals, SIGALRM);
Add_Signal (LL_Signals, SIGILL);
Add_Signal (LL_Signals, SIGABRT);
Add_Signal (LL_Signals, SIGFPE);
Add_Signal (LL_Signals, SIGSEGV);
Add_Signal (LL_Signals, SIGPIPE);
Add_All_Signals (Task_Signal_Mask);
Delete_Signal (Task_Signal_Mask, Abort_Signal);
Delete_Signal (Task_Signal_Mask, SIGALRM);
Delete_Signal (Task_Signal_Mask, SIGILL);
Delete_Signal (Task_Signal_Mask, SIGABRT);
Delete_Signal (Task_Signal_Mask, SIGFPE);
Delete_Signal (Task_Signal_Mask, SIGSEGV);
Delete_Signal (Task_Signal_Mask, SIGPIPE);
Delete_Signal (Task_Signal_Mask, SIGTRAP);
-- Not POSIX; this is left unmasked to keep SGI dbx happy.
pthread_init;
Delete_All_Signals (Reserved_Signals);
Add_Signal (Reserved_Signals, SIGILL);
Add_Signal (Reserved_Signals, SIGABRT);
Add_Signal (Reserved_Signals, SIGFPE);
Add_Signal (Reserved_Signals, SIGSEGV);
Add_Signal (Reserved_Signals, SIGPIPE);
Add_Signal (Reserved_Signals, Abort_Signal);
pthread_key_create (ATCB_Key, System.Null_Address, Result);
if Result = Failure then
raise Storage_Error; -- Insufficiant resources.
end if;
sigprocmask (SIG_SETMASK, Task_Signal_Mask, Old_Set, Result);
Assert (Result /= Failure, "GNULLI failure---sigprocmask");
T.LL_Entry_Point := null;
T.Thread := pthread_self;
pthread_setspecific (ATCB_Key, Pointer_to_Address (T), Result);
Assert (Result /= Failure, "GNULLI failure---pthread_setspecific");
end Initialize_LL_Tasks;
----------
-- Self --
----------
function Self return TCB_Ptr is
Temp : System.Address;
Result : Return_Code;
begin
pthread_getspecific (ATCB_Key, Temp, Result);
Assert (Result /= Failure, "GNULLI failure---pthread_getspecific");
return Address_to_Pointer (Temp);
end Self;
---------------------
-- Initialize_Lock --
---------------------
procedure Initialize_Lock
(Prio : System.Priority;
L : in out Lock)
is
Attributes : pthread_mutexattr_t;
Result : Return_Code;
begin
pthread_mutexattr_init (Attributes, Result);
if Result = Failure then
raise STORAGE_ERROR; -- should be ENOMEM
end if;
pthread_mutexattr_setprotocol (Attributes, PRIO_PROTECT, Result);
Assert (Result /= Failure,
"GNULLI failure---pthread_mutexattr_setprotocol");
pthread_mutexattr_setprio_ceiling (Attributes, Prio, Result);
Assert (Result /= Failure,
"GNULLI failure---pthread_mutexattr_setprio_ceiling");
pthread_mutex_init (pthread_mutex_t (L), Attributes, Result);
if Result = Failure then
raise STORAGE_ERROR; -- should be ENOMEM ???
end if;
end Initialize_Lock;
-------------------
-- Finalize_Lock --
-------------------
procedure Finalize_Lock (L : in out Lock) is
Result : Return_Code;
begin
pthread_mutex_destroy (pthread_mutex_t (L), Result);
Assert (Result /= Failure, "GNULLI failure--